package com.qf.controller;

import com.qf.bean.Item;
import com.qf.service.ItemService;
import com.qf.util.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * 商品模块的 controller
 */
@Controller
@RequestMapping("/item")
public class ItemController {

    @Autowired
    private ItemService itemService;


    @Value("${pic.types}")
    private String picTypes;


    @RequestMapping(value = "/update",method = RequestMethod.POST)
    public String update(Item item,HttpServletRequest req,Model model) throws IOException {
        // 1.判断修改时,是否传递了新的图片.
        MultipartFile picFile = item.getPicFile();
        if(picFile != null && picFile.getSize() > 0){
            // 上传了新的图片.
            UploadPic uploadPic = new UploadPic(req, model, picFile).invoke();
            if (uploadPic.is()) {
                return "item/item_update";
            }
            String pic = uploadPic.getPic();
            item.setPic(pic);
        }

        // 2.调用service,修改商品信息.
        Integer count = itemService.updateById(item);
        if(count == 1){
            // 修改成功,跳转到展示页面
            return "redirect:/item/list";
        }
        // 修改失败或没有修改,在回到该商品的修改页面.
        return "redirect:/item/update/" + item.getId();
    }



    // 跳转到修改页面.
    @RequestMapping(value = "/update/{id}",method = RequestMethod.GET)
    public String toUpdatePage(@PathVariable Integer id, Model model){
        //1. 调用service查询商品数据
        Item item = itemService.findById(id);
        model.addAttribute("item",item);

        //2. 转发到修改页面
        return "item/item_update";
    }




    // 删除商品信息.   http://localhost/item/delete/15    // Path
    @RequestMapping(value = "/delete/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public Integer delete(@PathVariable Integer id){

        Integer count = itemService.deleteById(id);

        return count;
    }


    /*
     * 限制文件的大小,   不超过5M
     * 限制文件的类型.   jpg,jpeg,png,gif
     * 避免损坏文件.
     */
    // 添加商品
    @RequestMapping("/add")
    public String add(@Valid Item item, BindingResult bindingResult, HttpServletRequest req, Model model) throws IOException {
        if(bindingResult.hasErrors()){
            // 参数不合法.返回到添加页面.
            return "item/item_add";
        }

        MultipartFile picFile = item.getPicFile();

        // 上传图片
        UploadPic uploadPic = new UploadPic(req, model, picFile).invoke();
        if (uploadPic.is()) return "item/item_add";
        String pic = uploadPic.getPic();

        // 将封装的pic设置到item中
        item.setPic(pic);

        // 调用service保存商品信息.
        Integer count = itemService.save(item);

        // 保存成功.
        if(count == 1){
            return "redirect:/item/list";
        }

        // 转发会添加页面
        model.addAttribute("addInfo","商品添加异常!!!");
        return "item/item_add";
    }


    // 展示商品
    @RequestMapping("/list")
    public String list(@RequestParam(value = "page",defaultValue = "1")Integer page,
                       @RequestParam(value = "size",defaultValue = "5")Integer size,
                       String name,
                       Model model){
        //1. 调用service查询商品和分页信息.
        PageInfo pageInfo = itemService.findItemByCondition(name,page,size);
        model.addAttribute("pageInfo",pageInfo);

        //2. 为了数据回显,将name放到request域中
        model.addAttribute("name",name);

        //3. 转发到商品展示页面
        return "item/item_list";
    }


    // 上传图片抽取出来一个内部类.
    private class UploadPic {
        private boolean myResult;
        private HttpServletRequest req;
        private Model model;
        private MultipartFile picFile;
        private String pic;

        public UploadPic(HttpServletRequest req, Model model, MultipartFile picFile) {
            this.req = req;
            this.model = model;
            this.picFile = picFile;
        }

        boolean is() {
            return myResult;
        }

        public String getPic() {
            return pic;
        }

        public UploadPic invoke() throws IOException {
            // 声明一个标识.
            boolean flag = false;

            // 0.校验文件类型.
            String[] types = picTypes.split(",");

            // 0.1 获得图片的原名字
            String fileName = picFile.getOriginalFilename();
            for (String type : types) {
                if(StringUtils.endsWithIgnoreCase(fileName,type)){
                    // 说明有匹配的类型,正确.
                    flag = true;
                    break;
                }
            }
            // 校验类型问题.
            if(flag == false){
                // 图片类型错误.
                model.addAttribute("picInfo","图片类型错误,要求为" + picTypes);
                myResult = true;
                return this;
            }

            // 0.5 校验图片是否损坏.
            BufferedImage bufferedImage = ImageIO.read(picFile.getInputStream());
            if(bufferedImage == null){
                // 图片损坏.
                model.addAttribute("picInfo","图片已经损坏,请更换图片.");
                myResult = true;
                return this;
            }
    //            1. 给图片重新起名字.

            //1.2 使用lang3下的StringUtils获取图片最后一个.后面的全部内容
            String typeName = StringUtils.substringAfterLast(fileName, ".").toLowerCase();
            //1.3 起个新名字
            String prefixName = UUID.randomUUID().toString();
            String newName = prefixName + "." + typeName;
    //            2. 将图片保存到本地.
            File file = new File(req.getServletContext().getRealPath("/static/images/") + "/" + newName);
            picFile.transferTo(file);
    //            3. 封装一个访问路径.
            pic = "http://localhost/static/images/" + newName;
            myResult = false;
            return this;
        }
    }
}
